<!--
 * @Author: ૮₍ ˙О˙₎ა
 * @Date: 2023-07-18 18:31:00
-->
<template>
  <div>
    <el-form :model="reqAddEditSpuParams" label-width="80px">
      <el-form-item label="SPU描述">
        <el-input placeholder="SPU名称" v-model="reqAddEditSpuParams.spuName" />
      </el-form-item>
      <el-form-item label="品牌">
        <el-select v-model="reqAddEditSpuParams.id" placeholder="请选择">
          <el-option
            v-for="item in trademarkList"
            :key="item.id"
            :label="item.tmName"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input v-model="reqAddEditSpuParams.description" type="textarea" placeholder="SPU描述" />
      </el-form-item>
      <el-form-item label="SPU图片">
        <el-upload
          v-model:file-list="fileList"
          action="/api/admin/product/upload"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性">
        <el-select v-model="attrId" placeholder="请选择属性">
          <el-option
            v-for="item in showSaleAttrList"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
        <el-button class="btnLeft" type="primary" @click="addAttrItem">添加销售属性</el-button>

        <el-table :data="reqAddEditSpuParams.spuSaleAttrList" border stripe>
          <el-table-column type="index" label="序号" width="80" />
          <el-table-column prop="saleAttrName" label="属性值" />
          <el-table-column label="属性值名称列表">
            <template #default="{ row }">
              <el-tag
                v-for="(tag, index) in row.spuSaleAttrValueList"
                :key="tag.id"
                closable
                :disable-transitions="false"
                @close="handleClose(row, index)"
              >
                {{ tag.saleAttrValueName }}
              </el-tag>
              <el-input
                v-if="row.isEdit"
                v-model="row.newAttrItem"
                ref="InputRef"
                @keyup.enter="showBtn(row)"
                @blur="showBtn(row)"
              />
              <el-button v-else class="button-new-tag ml-1" @click="showInput(row)" size="small">
                + New Ta
              </el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="100">
            <template #default>
              <el-button type="danger" :icon="Delete" circle />
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="reqSaveAddSpu">保存</el-button>
        <el-button>取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script lang="ts" setup>
import {
  reqSaveSpuInfo,
  reqSpuDetail,
  reqSpuImageList,
  reqSpuSaleAttrList,
  reqUpdateSpuInfo
} from '@/api/spu'
import { reqAllBaseTrademark, type reqBaseTrademarkDetailRes } from '@/api/trademark'
import { useCategoryStore } from '@/stores/category'
import type { ISpuPublic, ISpuSaleAttrList, ISpuSaleAttrListPublic } from '@/types/spu'
import { Delete, Plus } from '@element-plus/icons-vue'
import { ElMessage, type InputInstance, type UploadProps, type UploadUserFile } from 'element-plus'
import { storeToRefs } from 'pinia'
import { computed, nextTick, onMounted, ref } from 'vue'

const emit = defineEmits<{
  (e: 'setState', id: number): void
}>()

const props = defineProps<{
  spuId: number | string
}>()

const reqSaveAddSpu = async () => {
  const res = props.spuId
    ? await reqUpdateSpuInfo(reqAddEditSpuParams.value)
    : await reqSaveSpuInfo(reqAddEditSpuParams.value)

  if (res.code === 200) {
    ElMessage.success(props.spuId ? '编辑成功' : '添加成功')
    emit('setState', 1)
  }
}

const categoryStore = useCategoryStore()
const { category3Id } = storeToRefs(categoryStore)

// 添加编辑属性需要的参数
const reqAddEditSpuParams = ref<ISpuPublic>({
  spuName: '',
  tmId: '',
  category3Id: category3Id.value as number,
  description: '',
  spuImageList: [],
  spuSaleAttrList: []
})

//#region  渲染SpuList
const trademarkList = ref<reqBaseTrademarkDetailRes[]>([])
const saleAttrList = ref<ISpuSaleAttrList[]>([])

// 获取品牌和销售属性列表
const getTrademarkSaleList = async () => {
  const [res1, res2] = await Promise.all([reqAllBaseTrademark(), reqSpuSaleAttrList()])
  if (res1.code === 200 && res2.code) {
    trademarkList.value = res1.data
    saleAttrList.value = res2.data
  }
}

// 获取编辑数据
const getEditAttrList = async () => {
  const [res1, res2] = await Promise.all([
    reqSpuDetail(props.spuId as number),
    reqSpuImageList(props.spuId as number)
  ])
  if (res1.code === 200 && res2.code === 200) {
    reqAddEditSpuParams.value = res1.data
    reqAddEditSpuParams.value.spuImageList = res2.data
  }
}

onMounted(() => {
  getTrademarkSaleList()

  if (props.spuId) {
    getEditAttrList()
  }
})

//#endregion

//#region  销售属性逻辑

const attrId = ref()

const addAttrItem = () => {
  const attrItem = saleAttrList.value.find((item) => item.id === attrId.value)
  if (attrItem?.id) {
    reqAddEditSpuParams.value.spuSaleAttrList.push({
      baseSaleAttrId: attrItem.id,
      saleAttrName: attrItem.name,
      spuSaleAttrValueList: []
    })
  }
  attrId.value = ''
}

const InputRef = ref<InputInstance>()
const showBtn = (row: ISpuSaleAttrListPublic) => {
  row.isEdit = false
  if (row.newAttrItem) {
    row.spuSaleAttrValueList.push({
      saleAttrValueName: row.newAttrItem,
      baseSaleAttrId: row.baseSaleAttrId
    })
  }
}
const showInput = (row: ISpuSaleAttrListPublic) => {
  row.isEdit = true
  nextTick(() => {
    InputRef.value?.focus()
  })
}

// 删除一个tag
const handleClose = (row: ISpuSaleAttrListPublic, index: number) => {
  row.spuSaleAttrValueList.splice(index, 1)
}

// 计算需要显示的销售属性列表
const showSaleAttrList = computed(() => {
  if (!saleAttrList.value.length) return saleAttrList.value
  return saleAttrList.value.filter((item) => {
    return !reqAddEditSpuParams.value.spuSaleAttrList.some(
      (item2) => item2.baseSaleAttrId === item.id
    )
  })
})
//#endregion

//#region  图片列表渲染

const dialogImageUrl = ref('')
const dialogVisible = ref(false)

const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  const i = reqAddEditSpuParams.value.spuImageList.findIndex(
    (item) => item.imgUrl === uploadFile.url
  )
  reqAddEditSpuParams.value.spuImageList.splice(i, 1)
}

const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}

const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
  reqAddEditSpuParams.value.spuImageList.push({
    imgName: uploadFile.name,
    imgUrl: response.data
  })
}

const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type !== 'image/jpeg') {
    ElMessage.error('Avatar picture must be JPG format!')
    return false
  } else if (rawFile.size / 1024 / 1024 > 10) {
    ElMessage.error('Avatar picture size can not exceed 2MB!')
    return false
  }
  return true
}
const fileList = computed(() => {
  return reqAddEditSpuParams.value.spuImageList.map((item) => ({
    name: item.imgName,
    url: item.imgUrl
  }))
})
//#endregion
</script>

<script lang="ts">
export default {
  name: 'SpuFrom'
}
</script>

<style lang="scss" scoped>
.el-table {
  margin-top: 18px;
}
.btnLeft {
  margin-left: 10px;
}
</style>
